<template>
  <div class="app-container">
    <div class="head-container">
      <div v-if="crud.props.searchToggle">
        <!-- 搜索 -->
        <el-input
          v-model="query.name"
          clearable
          size="small"
          placeholder="输入地区名称搜索"
          style="width: 200px"
          class="filter-item"
          @keyup.enter.native="crud.toQuery"
        />
        <el-date-picker
          v-model="query.dateRange"
          type="daterange"
          range-separator="："
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          size="small"
          class="date-item"
          value-format="yyyy-MM-dd"
          @change="crud.toQuery"
        />
        <rrOperation />
      </div>
      <crudOperation :permission="permission" />
      <!--表单组件-->
      <el-dialog
        :close-on-click-modal="false"
        :before-close="crud.cancelCU"
        :visible.sync="crud.status.cu > 0"
        :title="crud.status.title"
        width="600px"
      >
        <el-form
          ref="form"
          :model="form"
          :rules="rules"
          size="small"
          label-width="100px"
        >
          <el-form-item label="地区名称" prop="name">
            <el-input v-model="form.name" style="width: 370px" />
          </el-form-item>
          <el-form-item label="地区级别" prop="level">
            <el-select
              v-model.number="form.level"
              filterable
              placeholder="请选择"
            >
              <el-option
                v-for="item in dict.region_level"
                :key="item.id"
                :label="item.label"
                :value="Number(item.value)"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="地区编码">
            <el-input v-model="form.code" style="width: 370px" />
          </el-form-item>
          <el-form-item label="状态" prop="status">
            <el-radio v-model="form.status" :label="true">启用</el-radio>
            <el-radio v-model="form.status" :label="false">禁用</el-radio>
          </el-form-item>
          <el-form-item label="地区排序" prop="regionSort">
            <el-input-number
              v-model="form.regionSort"
              :min="0"
              :max="999"
              :step="1"
              style="width: 370px"
            />
          </el-form-item>
          <el-form-item label="上级地区" prop="parentId">
            <treeselect
              v-model="form.parentId"
              :options="regions"
              :load-options="loadRegionOptions"
              :normalizer="normalizer"
              placeholder="请选择上级地区"
              :default-expand-level="1"
              style="width: 370px"
            />
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button type="text" @click="crud.cancelCU">取消</el-button>
          <el-button
            :loading="crud.status.cu === 2"
            type="primary"
            @click="crud.submitCU"
            >确认</el-button
          >
        </div>
      </el-dialog>
      <!--表格渲染-->
      <el-table
        ref="table"
        v-loading="crud.loading"
        :data="crud.data"
        lazy
        :load="loadRegionChildren"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        row-key="id"
        @selection-change="crud.selectionChangeHandler"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="name" label="地区名称" />
        <el-table-column prop="level" label="地区级别">
          <template slot-scope="scope">
            {{ dict.label.region_level[scope.row.level] }}
          </template>
        </el-table-column>
        <el-table-column prop="code" label="地区编码" />
        <el-table-column prop="regionSort" label="地区排序" width="100" />
        <el-table-column prop="status" label="状态">
          <template slot-scope="scope">
            <el-tag :type="scope.row.status ? 'success' : 'info'">
              {{ scope.row.status ? "启用" : "禁用" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createdAt" label="创建时间" />
        <el-table-column prop="updatedAt" label="更新时间" />
        <el-table-column
          v-if="checkPer(['admin', 'Region:edit', 'Region:del'])"
          label="操作"
          width="150px"
          align="center"
        >
          <template slot-scope="scope">
            <udOperation :data="scope.row" :permission="permission" />
          </template>
        </el-table-column>
      </el-table>
      <!--分页组件-->
      <pagination />
    </div>
  </div>
</template>

<script>
import crudRegion from "@/api/system/region";
import CRUD, { presenter, header, form, crud } from "@crud/crud";
import rrOperation from "@crud/RR.operation";
import crudOperation from "@crud/CRUD.operation";
import udOperation from "@crud/UD.operation";
import pagination from "@crud/Pagination";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import Treeselect from "@riophae/vue-treeselect";
import { LOAD_CHILDREN_OPTIONS } from "@riophae/vue-treeselect";

const defaultForm = {
  id: null,
  parentId: null,
  name: null,
  level: null,
  code: null,
  status: false,
  createdAt: null,
  updatedAt: null,
  regionSort: null,
};

export default {
  name: "Region",
  components: {
    Treeselect,
    pagination,
    crudOperation,
    rrOperation,
    udOperation,
  },
  mixins: [presenter(), header(), form(defaultForm), crud()],
  dicts: ["region_level", "region_status"],
  cruds() {
    return CRUD({
      title: "地区",
      url: "api/Region",
      crudMethod: { ...crudRegion },
    });
  },
  data() {
    return {
      regions: [
        {
          id: 0,
          label: "顶级地区",
          children: null,
        },
      ],
      params: {
        parentId: 0,
        page: 1,
        size: 10,
      },
      permission: {
        add: ["admin", "Region:add"],
        edit: ["admin", "Region:edit"],
        del: ["admin", "Region:del"],
      },
      rules: {
        name: [
          { required: true, message: "地区名称不能为空", trigger: "blur" },
        ],
        level: [
          {
            required: true,
            message: "地区级别，例如：1-大区，2-省市，3-县区不能为空",
            trigger: "blur",
          },
        ],
        regionSort: [
          { required: true, message: "排序不能为空", trigger: "blur" },
          { type: "number", message: "排序必须为数字", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    // 钩子：在获取表格数据之前执行，false 则代表不获取数据
    [CRUD.HOOK.beforeRefresh]() {
      if (!this.crud.params) {
        this.crud.params = { parentId: 0 };
      }

      // 确保 parentId 存在
      if (!this.crud.params.parentId && this.crud.params.parentId !== 0) {
        this.crud.params.parentId = 0;
      }

      // 添加搜索参数（如果有）
      if (this.query.name) {
        this.crud.params.name = this.query.name;
      } else {
        delete this.crud.params.name;
      }

      if (this.query.dateRange && this.query.dateRange.length === 2) {
        this.crud.params.startDate = this.query.dateRange[0];
        this.crud.params.endDate = this.query.dateRange[1];
      } else {
        delete this.crud.params.startDate;
        delete this.crud.params.endDate;
      }

      return true;
    },

    // CRUD钩子
    [CRUD.HOOK.afterToCU](crud, form) {
      // 处理父级ID
      if (form.id != null) {
        if (form.parentId === null) {
          form.parentId = 0;
        }
      } else {
        form.parentId = null;
      }

      // 确保 status 是 boolean 类型
      form.status = Boolean(form.status);

      // 确保 level 是数字类型
      if (form.level !== null) {
        form.level = Number(form.level);
      }
    },

    // 加载地区子节点数据
    loadRegionChildren(tree, treeNode, resolve) {
      const params = {
        parentId: tree.id,
        page: 1,
        size: 999,
      };
      // 展开子节点时只使用 parentId，不带搜索参数
      setTimeout(() => {
        crudRegion.query(params).then((res) => {
          if (!res || !res.content) {
            resolve([]);
            return;
          }

          const children = res.content.map((item) => ({
            ...item,
            hasChildren: item.subCount > 0,
          }));
          resolve(children);
        });
      }, 100);
    },

    // 异步加载地区选项
    async loadRegionOptions({ action, parentNode, callback }) {
      if (action === LOAD_CHILDREN_OPTIONS) {
        try {
          const res = await crudRegion.getRegionsTree(parentNode.id);
          parentNode.children = res.map((item) => ({
            id: item.id,
            label: item.name,
            children: item.subCount > 0 ? null : undefined,
          }));
          callback();
        } catch (err) {
          callback(new Error("Failed to load region options"));
        }
      }
    },

    // 格式化节点数据
    normalizer(node) {
      // 旧代码注释保留
      /*
      return {
        id: node.id,
        label: node.name || node.label,
        children: node.children
      }
      */

      // 新代码：只在有子节点时回 children 属性
      const normalized = {
        id: node.id,
        label: node.name || node.label,
      };

      // 只有当 children 存在时才添加这个属性
      if ("children" in node) {
        normalized.children = node.children;
      }

      return normalized;
    },

    // 可以添加一个刷新方法
    async refreshTreeData() {
      await this.initData();
    },

    // 在表单提交成功后刷新
    [CRUD.HOOK.afterSubmit]() {
      this.initData();
    },

    // 在删除成功后刷新
    [CRUD.HOOK.afterDelete]() {
      this.initData();
      // window.location.reload(true)
    },

    // 可以添加一个手动刷新方法
    refreshTable() {
      this.$refs.table.store.states.lazyTreeNodeMap = {};
      this.crud.refresh();
    },

    // 添加初始化方法
    initData() {
      // 直接调用查询方法
      // crudRegion.query(this.params)
      //   .then(res => {
      //     if (res && res.content) {
      //       // 处理数据并设置到表格
      //       const data = res.content.map(item => ({
      //         ...item,
      //         hasChildren: item.subCount > 0,
      //         leaf: item.subCount === 0
      //       }))
      //       this.crud.data = data
      //     }
      //   })
      //   .catch(error => {
      //   })
    },

    // 添加一个手动触发查询的方法
    triggerQuery() {
      if (this.crud && this.crud.crudMethod && this.crud.crudMethod.query) {
        this.crud.crudMethod
          .query({ parentId: 0 })
          .then((res) => {})
          .catch((err) => {});
      } else {
      }
    },

    // 修改展开/收起处理方法
    handleExpandChange(row, expanded) {
      if (!expanded) {
        // 清除展开状态
        this.$set(this.$refs.table.store.states.lazyTreeNodeMap, row.id, []);
        this.$refs.table.store.states.treeData = {};
      }
    },

    // 处理表单数据类型
    handleFormData(data) {
      return {
        ...data,
        status: Boolean(data.status),
        level: Number(data.level),
      };
    },

    [CRUD.HOOK.beforeToEdit](crud, form) {
      form = this.handleFormData(form);
    },

    [CRUD.HOOK.beforeToAdd](crud, form) {
      form = this.handleFormData(form);
    },
  },

  // 加created钩子
  created() {
    this.$nextTick(() => {
      this.initData();
    });
  },

  // 添加mounted钩子
  mounted() {},
};
</script>

<style>
/* Treeselect 组件样式调整 */
.vue-treeselect__control {
  border-radius: 4px;
  line-height: 32px;
  padding: 0 8px;
}

.vue-treeselect__placeholder,
.vue-treeselect__single-value {
  line-height: 32px;
}

.vue-treeselect__option {
  padding: 5px 15px;
}

.vue-treeselect__option--highlight {
  background: #f5f7fa;
}

.vue-treeselect__label {
  font-weight: normal;
}

.vue-treeselect--focused .vue-treeselect__control {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

/* 自定义提示文本式 */
.vue-treeselect__no-options,
.vue-treeselect__no-children {
  padding: 8px 15px;
  color: #909399;
  font-size: 14px;
}

/* 添加树形表格的样式 */
.el-table__expand-icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  cursor: pointer;
}

.el-table__expand-icon--expanded {
  transform: rotate(90deg);
}

.el-table__expand-icon > .el-icon {
  font-size: 14px;
  color: #409eff;
}

.el-table .el-table__row--level-0 {
  font-weight: bold;
}

/* 添加搜索区域样式 */
/* .filter-container {
  padding-bottom: 10px;
  margin-bottom: 10px;
}
.filter-item {
  margin-right: 10px;
  width: 200px;
} */
</style>